package svgedit.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.event.MenuListener;

import svgedit.gui.actions.*;

import svgedit.svg.SVGDocument;
import svgedit.svg.SVGViewport;
import svgedit.xml.*;

/** Displays a window containing a SVG view, toolbar and menu. */
@SuppressWarnings("serial")
public class Frame extends JFrame {

	private Map<Integer, JButton> buttons = new HashMap<Integer, JButton>();
	private Map<Integer, JButton> buttons2 = new HashMap<Integer, JButton>();
	public static final int CIRCLE = 1;
	public static final int RECTANGLE = 2;
	public static final int LINE = 3;
	public static final int SELECT = 4;
	public static final int FILL = 5;
	public static final int STROKE_COLOR = 6;
	public static final int STROKE_WIDTH = 7;
	public static final int delete = 8;
	public static final int noFill = 9;
	public static final int noStroke = 10;

	JFileChooser dialog = new JFileChooser();


	/** User preferences */
	private Preferences preferences;

	/** The document displayed by the frame */
	private SVGDocument document;

	/** An SVG view of the current document */
	public View view;

	// Actions available from the FILE Menu */
	private Action newAction;
	private Action openAction;
	private Action saveAction;
	private Action saveasAction;
	private Action documentPropertiesAction;
	private Action quitAction;

	// Actions available from the EDIT Menu */
	private Action selectAllAction;
	private Action groupAction;
	private Action ungroupAction;
	private Action deleteAction;

	/** Creates a frame with a new, empty document. */
	public Frame() {

		setDefaultCloseOperation(EXIT_ON_CLOSE);

		preferences = new Preferences();
		// Create view
		view = new View(this);

		// Create all actions presented by the FILE Menu
		newAction = new NewAction(this);
		openAction = new OpenDocumentAction(this);
		saveAction = new SaveAction(this);
		saveasAction = new SaveAsAction(this);
		documentPropertiesAction = new DocumentPropertiesAction(this);
		quitAction = new QuitAction(this);

		// Create all actions presented by the EDIT Menu
		selectAllAction = new SelectAllAction(this);
		groupAction = new GroupAction(this);
		ungroupAction = new UngroupAction(this);
		deleteAction = new DeleteAction(this);

		// Associate keyboard shortcuts with actions
		newAction.putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_N, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
		openAction.putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
		saveAction.putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
		saveasAction.putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S,ActionEvent.CTRL_MASK + ActionEvent.SHIFT_MASK));
		documentPropertiesAction.putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));

		// Create menus
		JMenuBar menuBar = new JMenuBar();
		add(menuBar, BorderLayout.NORTH);

		JMenu fileMenu = new JMenu("File");
		JMenu editMenu = new JMenu("Edit");
		JMenu insertMenu = new JMenu("Insert");
		
		JMenuItem insertRect = new JMenuItem("Insert Recangle");
		insertRect.setActionCommand("insertRect");
		JMenuItem insertCircle = new JMenuItem("Insert Circle");
		insertCircle.setActionCommand("insertCircle");
		JMenuItem insertLine = new JMenuItem("Insert Line");
		insertLine.setActionCommand("insertLine");

		// Assign FILE Menu Items
		fileMenu.add(new JMenuItem(newAction));
		fileMenu.addSeparator();
		fileMenu.add(new JMenuItem(openAction));
		fileMenu.addSeparator();
		fileMenu.add(new JMenuItem(saveAction));
		fileMenu.add(new JMenuItem(saveasAction));
		fileMenu.addSeparator();
		fileMenu.add(new JMenuItem(documentPropertiesAction));
		fileMenu.addSeparator();
		fileMenu.add(new JMenuItem(quitAction));
		
		// Assign INSERT Menu Items
		insertMenu.add(insertRect);
		fileMenu.addSeparator();
		insertRect.addActionListener(view);
		insertMenu.add(insertCircle);
		fileMenu.addSeparator();
		insertCircle.addActionListener(view);
		insertMenu.add(insertLine);
		fileMenu.addSeparator();
		insertLine.addActionListener(view);


		// Assign EDIT Menu Items
		editMenu.add(new JMenuItem(selectAllAction));
		editMenu.addSeparator();
		editMenu.add(new JMenuItem(groupAction));
		editMenu.add(new JMenuItem(ungroupAction));
		editMenu.addSeparator();
		editMenu.add(new JMenuItem(deleteAction));

		menuBar.add(fileMenu);
		menuBar.add(insertMenu);
		menuBar.add(editMenu);

		//Create Buttons for INSERT tool
		JButton editButton = new JButton(new ImageIcon("images/edit.gif"));//button to select shape and start edit it.
		editButton.setActionCommand("editButton");
		editButton.addActionListener(view);
		JButton insertRectButton = new JButton(new ImageIcon("images/rect.gif"));
		insertRectButton.setActionCommand("insertRectButton");
		insertRectButton.addActionListener(view);
		JButton insertCircleButton =  new JButton(new ImageIcon("images/circle.gif"));
		insertCircleButton.setActionCommand("insertCircleButton");
		insertCircleButton.addActionListener(view);
		JButton insertLineButton = new JButton(new ImageIcon("images/line.gif"));
		insertCircleButton.setActionCommand("insertLineButton");
		insertLineButton.addActionListener(view);

		buttons.put(Frame.SELECT, editButton);
		buttons.put(Frame.CIRCLE, insertCircleButton);
		buttons.put(Frame.RECTANGLE, insertRectButton);
		buttons.put(Frame.LINE, insertLineButton);

		//Create Buttons for OBJECT tool		
		JButton fillColorButton = null;
		fillColorButton = new JButton("Fill Color");
		fillColorButton.setActionCommand("fillColor");
		fillColorButton.addActionListener(view);
		JButton strokeColorButton = null;
		strokeColorButton = new JButton("Stroke Color");
		strokeColorButton.setActionCommand("strokeColor");
		strokeColorButton.addActionListener(view);
		JButton strokeWidthButton = null;
		strokeWidthButton = new JButton("Stroke Width");
		strokeWidthButton.setActionCommand("strokeWidth");
		strokeWidthButton.addActionListener(view);
		JButton deleteButton = new JButton("delete");
		deleteButton.setActionCommand("delete");
		deleteButton.addActionListener(view);
		JButton noFillButton = new JButton("Transparent Fill");
		noFillButton.setActionCommand("noFillButton");
		noFillButton.addActionListener(view);
		JButton noStrokeButton = new JButton("Transparent stroke");
		noStrokeButton.setActionCommand("noStrokeButton");
		noStrokeButton.addActionListener(view);

		buttons2.put(Frame.FILL, fillColorButton);
		buttons2.put(Frame.STROKE_COLOR, strokeColorButton);
		buttons2.put(Frame.STROKE_WIDTH, strokeWidthButton);
		buttons2.put(Frame.delete, deleteButton);
		buttons2.put(Frame.noFill, noFillButton);
		buttons2.put(Frame.noStroke, noStrokeButton);

		//Create Toolbars
		JToolBar insertToolBar = new JToolBar("Insert",JToolBar.VERTICAL);
		add(insertToolBar, BorderLayout.WEST);
		JToolBar objectToolBar = new JToolBar("Object",JToolBar.VERTICAL);
		add(objectToolBar, BorderLayout.EAST);

		insertToolBar.add(editButton);
		insertToolBar.add(insertRectButton);
		insertToolBar.add(insertCircleButton);
		insertToolBar.add(insertLineButton);

		objectToolBar.add(fillColorButton);
		objectToolBar.add(strokeColorButton);
		objectToolBar.add(strokeWidthButton);
		objectToolBar.add(deleteButton);
		objectToolBar.add(noFillButton);
		objectToolBar.add(noStrokeButton);

		getContentPane().add(view);

		newFile();
		deleteSelected();
		// Set an initial view size in case the document size is based on the view
		view.setSize(new Dimension(480, 360));

		// Size the view to the document
		view.setPreferredSize(new Dimension((int) document.getWidth().getValue(), (int) document.getHeight().getValue()));
		pack();
	}

	/** Gets the preferences object to use for getting and setting user defaults.
	 *
	 * @return the preferences object associated with this frame
	 */
	public Preferences getPreferences() {

		return preferences;
	}

	/** Gets the document currently displayed in the frame.
	 *
	 * @return an SVG document
	 */
	public SVGDocument getDocument() {

		return document;
	}

	/** Sets the document currently displayed in the frame.
	 *
	 * @param document the document to display
	 * @param file the file the document was loaded from, or null if it's a new file
	 */
	private void setDocument(SVGDocument document, File file) {

		this.document = document;
		view.setDocument(document);
		setFile(file);
	}

	/** Gets the view presenting the document for this frame. */
	public View getView() {

		return view;
	}

	/**
	 * Set the filename of the current document. Sets the frame's title and
	 * enables the appropriate save menu items.
	 * 
	 * @param file
	 *            the filename of the current document, or null if the document
	 *            is new and has no filename
	 */
	private void setFile(File file) {
		document.setFile(file);

		if (file != null)
			setTitle(file.getName() + " - SVGEdit");
		else
			setTitle("SVGEdit");
	}

	/** Sets the document to a new document with no associated file. */
	public final void newFile() {
		if(view.rects!=null) {

			Iterator<Rect> rectIterator = view.rects.iterator();
			while (rectIterator.hasNext()) {
				rectIterator.next().setIsSelected(true);
			}
		}

		if (view.circles!=null) {
			Iterator<Circle> circIterator = view.circles.iterator();

			while (circIterator.hasNext()) {
				circIterator.next().setIsSelected(true);
			}

		}

		if (view.lines!=null) {
			Iterator<Line> lineIterator = view.lines.iterator();

			while (lineIterator.hasNext()) {
				lineIterator.next().setIsSelected(true);
			}
		}

		SVGDocument doc = new SVGDocument(view);
		setDocument(doc, null);
	}

	/** Loads a file and sets it as the current document.  Displays an error
	 *  message and leaves the current document unchanged if the document cannot
	 *  be opened.
	 *
	 * @param file the file to load
	 */
	public final void openFile(File file) {
		newFile();
		deleteSelected();
		try {
			SVGDocument doc = XMLReader.read(file, view);
			setDocument(doc, file);
		} catch (IOException e) {
			JOptionPane.showMessageDialog(getRootPane(), e.getMessage(), "Unable to open file", JOptionPane.ERROR_MESSAGE);
		}
	}

	public Map<Integer, JButton> getButtons() {
		return buttons;
	}
	public Map<Integer, JButton> getButtons2() {
		return buttons2;
	}

	public void setButtons2(Map<Integer, JButton> buttons2) {
		this.buttons2 = buttons2;
	}    


	protected void processWindowEvent(WindowEvent e)
	{
		if (e.getID()==WindowEvent.WINDOW_CLOSING && view.getSaveState()!=0)
		{
			int exit =JOptionPane.showConfirmDialog(this,"Do you want to save before exit?"
					,"Confrim Exit", JOptionPane.YES_NO_CANCEL_OPTION);
			if (exit==JOptionPane.YES_OPTION){
				new SaveAsUtil().SaveAs(this);
				System.exit(0);
			}else if (exit==JOptionPane.NO_OPTION) {
				System.exit(0);
			}else if (exit==JOptionPane.CANCEL_OPTION) {		
			}
		}
		else
			super.processWindowEvent(e);
	}
	
	// delete all selected objects
	public final void deleteSelected() {
		if(view.rects!=null) {

			Iterator<Rect> rectIterator = view.rects.iterator();

			while (rectIterator.hasNext()) {
				if (rectIterator.next().getIsSelected()==true) {
					rectIterator.remove();
					repaint();
				}
			}
		}

		if (view.circles!=null) {
			Iterator<Circle> circIterator = view.circles.iterator();

			while (circIterator.hasNext()) {
				if (circIterator.next().getIsSelected()==true) {
					circIterator.remove();
					repaint();
				}
			}
		}

		if (view.lines!=null) {
			Iterator<Line> lineIterator = view.lines.iterator();

			while (lineIterator.hasNext()) {
				if (lineIterator.next().getIsSelected()==true) {
					lineIterator.remove();
					repaint();
				}
			}
		}


	}

}
